<html>
<head>
  <title>Endpoint Resolver</title>
</head>

<body>
  <h1>Endpoint Resolver</h1>
  
  <p>
    The Endpoint Resolver is a simple library that takes a URL and returns the final destination of that URL. It tries to follow a <code>Location:</code> header.
  </p>
  
  <h2>How it works</h2>
  
  <p>
    Given the URL, it gets passes to a server side resolver that hits the URL to get the headers. If a <code>Location:</code> header appears it is a redirect (ignoring 301, 302 for now, so a 200 + Location would count).
  </p>
  
  <p>
    Since this happens via JSONP, it happens asynchronously via appending the script to the DOM. This is why you pass in a callback that will be passed the new URL, and the original one.
  </p>
  
  <p>
    If the URL has been changed they will of course be different, and a simple helper <code>Endpoint.isRedirecting(url, orig)</code> will do that test for you.
  </p>
  
  <h2>Why?</h2>
  
  <p>
    The reason I built this was for a Twitter client. Seeing tinyurl / snurl / is.gd / twurl / .... URLs is ugly, and it can be scary not knowing where you are going, so wouldn't it be nice to convert them back to the real URL?
  </p>
  
  <p>
    I built a <a href="twitter-resolveurl.user.js">Twitter Resolve URL Greasemonkey script</a> to do just that.
  </p>
  
  <h2>Examples</h2>
  
  <pre>
    // Simplest version
    Endpoint.resolve('http://snurl.com/2luj3', function(url) { 
      alert(url); 
    });
    
    // Used in the form below
    Endpoint.resolve(
      document.getElementById('testurl').value, 
      function(url) { alert(url); }
    );
    
    // Using the original URL to work out if it has changed
    Endpoint.resolve(
      document.getElementById('testurl').value, 
      function(url, orig) { 
        alert(url); 
        alert(Endpoint.isRedirecting(url, orig));
      }
    );
    
    // How it is used in the Twitter Endpoint Resolver
    Endpoint.resolve(url, function(resulturl, originalurl) {
      if (!Endpoint.isRedirecting(resulturl, originalurl)) return;
      
      newtext = newtext.replace(originalurl, resulturl, "g");
      jQuery(el).html(newtext);
    });
  </pre>
  
  <h2>Endpoint Resolver Demo</h2>
    
  <input type="text" id="testurl" value="http://snurl.com/2luj3" size="40"/>
  <input type="button" value="endpoint" onclick="Endpoint.resolve(document.getElementById('testurl').value, function(url, orig) { document.getElementById('result').innerHTML = 'URL Resolved to: ' + url + ' (is redirecting? ' + Endpoint.isRedirecting(url, orig) + '))';});">

  <div id="result" style="padding: 8px;"></div>
  
  <h2>The Code</h2>
  
  <p>
    All of the code (JavaScript / PHP) is <a href="http://code.google.com/p/endpoint-resolver">available thanks to Google Code</a>. I wanted to host this service on App Engine, but couldn't find a way to get the correct headers from the fetch() as it seems to automatically follow the redirects so you end up with the final page.
  </p>
  
  <script type="text/javascript" src="endpoint.js"></script>
</body>

</html>
